﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Web.Script.Serialization;
using System.Xml.Linq;
//
using PerceptiveMCAPI.Types.Internal;
//
namespace PerceptiveMCAPI.Types
{
	public class listClientsOutput : Api_BaseOutput
	{
		public listClientsResults result { get; set; }
		public listClientsParms inputParms { get; private set; }
		//
		public listClientsOutput( listClientsInput input )
			: base( input )
		{
			inputParms = input.parms;
			result = new listClientsResults();
		}
		// --------------------------------------------------- tostring
		public override string ToString()
		{
			return "ToString() not yet implemented";
		}

		#region ================================================================== format setup
		// ---- serial
		internal void Format( string api_Request, string api_Response )
		{
			this.api_Request = api_Request;
			this.api_Response = api_Response;
			// ----------------------------------
			if ( this.api_OutputType == EnumValues.OutputType.JSON )
				outputJSON();
			else if ( this.api_OutputType == EnumValues.OutputType.XML )
				outputXML();
		}
		// ---- xmlrpc
		internal void Format( x_listClients rpcResult )
		{
			this.api_Request = EnumValues.NotSupplied;
			this.api_Response = EnumValues.NotSupplied;
			// ------------------------
			this.result = FormatResults( rpcResult );
		}
		#endregion

		#region  ===================================================================== format result
		// ---------------------------------------------------------- outputXML
		protected void outputXML()
		{
			XElement xml = XElement.Parse( this.api_Response );
			// error check
			Api_Error error = apiSerial.GetXmlOutputError( xml );
			if ( error != null )
			{
				this.api_ErrorMessages.Add( error );
				return;
			}
			// -------------------------------------------- get values

			try
			{
				int it; double dbl;
				listClientsResults results = new listClientsResults();
				XElement desktop = xml.Element( "desktop" );
				XElement mobile = xml.Element( "mobile" );
				// ---------------------------------------------------------- desktop
				if ( desktop.HasElements )
				{
					double.TryParse( desktop.Element( "penetration" ).Value, out dbl );
					results.desktop.penetration = dbl;
					//
					if ( desktop.Element( "clients" ) != null && desktop.Element( "clients" ).HasElements )
					{
						IEnumerable<XElement> desktop_clients = desktop.Element( "clients" ).Elements( "struct" );
						foreach ( XElement dc in desktop_clients )
						{
							listClientsResults.ClientInfo info = new listClientsResults.ClientInfo();
							//
							info.client = dc.Element( "client" ).Value ?? "";
							int.TryParse( dc.Element( "members" ).Value, out it );
							info.members = it;
							double.TryParse( dc.Element( "percent" ).Value, out dbl );
							info.percent = dbl;
							info.icon = dc.Element( "icon" ).Value ?? "";
							//
							results.desktop.clients.Add( info );
						}
					}
				}

				// ---------------------------------------------------------- mobile
				if ( mobile.HasElements )
				{
					double.TryParse( mobile.Element( "penetration" ).Value, out dbl );
					results.mobile.penetration = dbl;
					//
					if ( mobile.Element( "clients" ) != null && mobile.Element( "clients" ).HasElements )
					{
						IEnumerable<XElement> mobile_clients = mobile.Element( "clients" ).Elements( "struct" );
						foreach ( XElement dc in mobile_clients )
						{
							listClientsResults.ClientInfo info = new listClientsResults.ClientInfo();
							//
							info.client = dc.Element( "client" ).Value ?? "";
							int.TryParse( dc.Element( "members" ).Value, out it );
							info.members = it;
							double.TryParse( dc.Element( "percent" ).Value, out dbl );
							info.percent = dbl;
							info.icon = dc.Element( "icon" ).Value ?? "";
							//
							results.mobile.clients.Add( info );
						}
					}
				}
				// ---------------------------------------------------------- result
				this.result = results;
			}
			catch ( Exception ex )
			{
				this.api_ErrorMessages.Add( apiException.FormatError( ex ) );
			}
		}
		// ---------------------------------------------------------- outputJSON
		protected void outputJSON()
		{
			JavaScriptSerializer jss = new JavaScriptSerializer();

			try
			{
				if ( this.api_Response.Contains( EnumValues.JSONErrorString ) )
				{
					Api_Error err = jss.Deserialize<Api_Error>( this.api_Response );
					this.api_ErrorMessages.Add( err );
				}
				else
				{
					x_listClients jsonResult = jss.Deserialize<x_listClients>( this.api_Response );
					this.result = FormatResults( jsonResult );
				}
			}
			catch ( Exception ex )
			{
				this.api_ErrorMessages.Add( apiException.FormatError( ex ) );
			}
		}
		// -----------------------------------------------------
		protected listClientsResults FormatResults( x_listClients x_results )
		{
			double dbl; int it;
			var results = new listClientsResults();
			// ------------------------------------------------------------ desktop
			IDictionary desktop = x_results.desktop as IDictionary;
			if ( desktop != null && desktop.Contains( "penetration" ) )
			{
				double.TryParse( desktop["penetration"].ToString(), out dbl );
				results.desktop.penetration = dbl;
			}
			//
			if ( desktop != null && desktop.Contains( "clients" ) )
			{
				object[] desktop_clients = desktop["clients"] as object[];
				foreach ( object oclient in desktop_clients )
				{
					IDictionary ci = oclient as IDictionary;
					listClientsResults.ClientInfo client = new listClientsResults.ClientInfo();
					//
					int.TryParse( ci["members"].ToString(), out it );
					client.members = it;
					client.icon = ci["icon"].ToString();
					double.TryParse( ci["percent"].ToString(), out dbl );
					client.percent = dbl;
					client.client = ci["client"].ToString();
					results.desktop.clients.Add( client );
				}
			}
			// ------------------------------------------------------------ mobile
			IDictionary mobile = x_results.mobile as IDictionary;
			if ( mobile != null && mobile.Contains( "penetration" ) )
			{
				double.TryParse( mobile["penetration"].ToString(), out dbl );
				results.mobile.penetration = dbl;
			}
			//
			if ( mobile != null && mobile.Contains( "clients" ) )
			{
				object[] mobile_clients = mobile["clients"] as object[];
				foreach ( object oclient in mobile_clients )
				{
					IDictionary ci = oclient as IDictionary;
					listClientsResults.ClientInfo client = new listClientsResults.ClientInfo();
					//
					int.TryParse( ci["members"].ToString(), out it );
					client.members = it;
					client.icon = ci["icon"].ToString();
					double.TryParse( ci["percent"].ToString(), out dbl );
					client.percent = dbl;
					client.client = ci["client"].ToString();
					results.mobile.clients.Add( client );
				}
			}
			//------------------- 
			return results;
		}
		//
		#endregion
	}
}
